package org.dftproject.genesis.ui.figures;

import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureListener;
import org.eclipse.draw2d.FocusEvent;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

public class SWTFigure extends Figure {

	private final Control control;

	public SWTFigure(final Control control) {
		setOpaque(true);

		this.control = control;
		control.addTraverseListener(new TraverseListener() {

			public void keyTraversed(final TraverseEvent e) {
				if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
					Display.getCurrent().asyncExec(new Runnable() {

						public void run() {
							requestFocus();
							control.getParent().setFocus();
							control.getParent().traverse(e.detail);
						}
					});
					e.doit = false;
				}
			}

		});

		setRequestFocusEnabled(true);
		setFocusTraversable(true);
		addFigureListener(new FigureListener() {

			public void figureMoved(IFigure source) {
				Rectangle clientArea = getClientArea().getCopy();
				Point size = control.computeSize(-1, -1);
				clientArea.expand(0, (size.y - clientArea.height) / 2);
				control.setBounds(clientArea.x, clientArea.y, clientArea.width, clientArea.height);
			}

		});
	}

	@Override
	public void handleFocusGained(FocusEvent event) {
		super.handleFocusGained(event);
		control.setFocus();
	}

	@Override
	public void paint(Graphics graphics) {
	}

	@Override
	public Dimension getPreferredSize(int wHint, int hHint) {
		Point size = control.computeSize(wHint, hHint);
		if (wHint > -1)
			size.x = Math.min(wHint, size.x);
		if (hHint > -1)
			size.y = Math.min(hHint, size.y);
		return new Dimension(size.x, size.y);
	}

	public Control getControl() {
		return control;
	}

}
